home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Net / UserAgent / Detect.php
PHP Script  |  2004-03-24  |  38KB  |  908 lines

  1. <?php
  2. // {{{ license
  3.  
  4. // +----------------------------------------------------------------------+
  5. // | PHP version 4.2                                                      |
  6. // +----------------------------------------------------------------------+
  7. // | Copyright (c) 1997-2003 The PHP Group                                |
  8. // +----------------------------------------------------------------------+
  9. // | This source file is subject to version 2.0 of the PHP license,       |
  10. // | that is bundled with this package in the file LICENSE, and is        |
  11. // | available at through the world-wide-web at                           |
  12. // | http://www.php.net/license/2_02.txt.                                 |
  13. // | If you did not receive a copy of the PHP license and are unable to   |
  14. // | obtain it through the world-wide-web, please send a note to          |
  15. // | license@php.net so we can mail you a copy immediately.               |
  16. // +----------------------------------------------------------------------+
  17. // | Authors: Dan Allen <dan@mojavelinux.com>                             |
  18. // |          Jason Rust <jrust@php.net>                                  |
  19. // +----------------------------------------------------------------------+
  20.  
  21. // $Id: Detect.php,v 1.12 2004/03/10 20:22:34 jrust Exp $
  22.  
  23. // }}}
  24. // {{{ constants
  25.  
  26. define('NET_USERAGENT_DETECT_BROWSER',  'browser');
  27. define('NET_USERAGENT_DETECT_OS',       'os');
  28. define('NET_USERAGENT_DETECT_FEATURES', 'features');
  29. define('NET_USERAGENT_DETECT_QUIRKS',   'quirks');
  30. define('NET_USERAGENT_DETECT_ACCEPT',   'accept');
  31. define('NET_USERAGENT_DETECT_ALL',      'all');
  32.  
  33. // }}}
  34. // {{{ class Net_UserAgent_Detect
  35.  
  36. /**
  37.  * The Net_UserAgent_Detect object does a number of tests on an HTTP user
  38.  * agent string.  The results of these tests are available via methods of
  39.  * the object.  Note that all methods in this class can be called
  40.  * statically.  The constructor and singleton methods are only retained
  41.  * for BC.
  42.  *
  43.  * This module is based upon the JavaScript browser detection code
  44.  * available at http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html.
  45.  * This module had many influences from the lib/Browser.php code in
  46.  * version 1.3 of Horde.
  47.  *
  48.  * @author   Jason Rust <jrust@php.net>
  49.  * @author   Dan Allen <dan@mojavelinux.com>
  50.  * @author   Chuck Hagenbuch <chuck@horde.org>
  51.  * @author   Jon Parise <jon@horde.org>
  52.  * @package  Net_UserAgent
  53.  */
  54.  
  55. // }}}
  56. class Net_UserAgent_Detect {
  57.     // {{{ constructor
  58.  
  59.     function Net_UserAgent_Detect($in_userAgent = null, $in_detect = null)
  60.     {
  61.         $this->detect($in_userAgent, $in_detect);
  62.     }
  63.  
  64.     // }}}
  65.     // {{{ singleton
  66.  
  67.     /**
  68.      * To be used in place of the contructor to return only open instance.
  69.      *
  70.      * @access public 
  71.      * @return object Net_UserAgent_Detect instance
  72.      */
  73.     function &singleton($in_userAgent = null, $in_detect = null) 
  74.     { 
  75.         static $instance;
  76.        
  77.         if (!isset($instance)) { 
  78.             $instance = new Net_UserAgent_Detect($in_userAgent, $in_detect); 
  79.         }
  80.         
  81.         return $instance; 
  82.     }
  83.  
  84.     // }}}
  85.     // {{{ detect()
  86.  
  87.     /**
  88.      * Detect the user agent and prepare flags, features and quirks
  89.      * based on what is found
  90.      *
  91.      * This is the core of the Net_UserAgent_Detect class.  It moves its
  92.      * way through the user agent string setting up the flags based on
  93.      * the vendors and versions of the browsers, determining the OS and
  94.      * setting up the features and quirks owned by each of the relevant
  95.      * clients.  Note that if you are going to be calling methods of
  96.      * this class statically then set all the parameters using th
  97.      * setOption()
  98.      *
  99.      * @param  string $in_userAgent (optional) User agent override.  
  100.      * @param  mixed $in_detect (optional) The level of checking to do. 
  101.      *
  102.      * @access public
  103.      * @return void
  104.      */
  105.     function detect($in_userAgent = null, $in_detect = null)
  106.     {
  107.         static $hasRun;
  108.         if (!empty($hasRun)) {
  109.             return;
  110.         }
  111.  
  112.         $hasRun = true;
  113.         // {{{ set up static properties
  114.  
  115.         $options = &Net_UserAgent_Detect::_getStaticProperty('options');
  116.         $in_userAgent = isset($options['userAgent']) && is_null($in_userAgent) ? $options['userAgent'] : null;
  117.         $in_detect = isset($options['detectOptions']) && is_null($in_detect) ? $options['detectOptions'] : null;
  118.  
  119.         // User agent string that is being analyzed
  120.         $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent');
  121.  
  122.         // Array that stores all of the flags for the vendor and version
  123.         // of the different browsers
  124.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  125.         $browser = array_flip(array('ns', 'ns2', 'ns3', 'ns4', 'ns4up', 'nav', 'ns6', 'ns6up', 'gecko', 'ie', 'ie3', 'ie4', 'ie4up', 'ie5', 'ie5_5', 'ie5up', 'ie6', 'ie6up', 'opera', 'opera2', 'opera3', 'opera4', 'opera5', 'opera5up', 'aol', 'aol3', 'aol4', 'aol5', 'aol6', 'aol7', 'webtv', 'aoltv', 'tvnavigator', 'hotjava', 'hotjava3', 'hotjava3up', 'konq', 'safari'));
  126.         
  127.         // Array that stores all of the flags for the operating systems,
  128.         // and in some cases the versions of those operating systems (windows)
  129.         $os = &Net_UserAgent_Detect::_getStaticProperty('os');
  130.         $os = array_flip(array('win', 'win95', 'win16', 'win31', 'win9x', 'win98', 'winme', 'win2k', 'winxp', 'winnt', 'os2', 'mac', 'mac68k', 'macppc', 'linux', 'unix', 'vms', 'sun', 'sun4', 'sun5', 'suni86', 'irix', 'irix5', 'irix6', 'hpux', 'hpux9', 'hpux10', 'aix', 'aix1', 'aix2', 'aix3', 'aix4', 'sco', 'unixware', 'mpras', 'reliant', 'dec', 'sinix', 'freebsd', 'bsd'));
  131.  
  132.         // Array which stores known issues with the given client that can
  133.         // be used for on the fly tweaking so that the client may recieve
  134.         // the proper handling of this quirk.
  135.         $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
  136.         $quirks = array(
  137.                 'must_cache_forms'         => false,
  138.                 'popups_disabled'          => false,
  139.                 'empty_file_input_value'   => false,
  140.                 'cache_ssl_downloads'      => false,
  141.                 'scrollbar_in_way'         => false,
  142.                 'break_disposition_header' => false,
  143.                 'nested_table_render_bug'  => false);
  144.  
  145.         // Array that stores credentials for each of the browser/os
  146.         // combinations.  These allow quick access to determine if the
  147.         // current client has a feature that is going to be implemented
  148.         // in the script.
  149.         $features = &Net_UserAgent_Detect::_getStaticProperty('features');
  150.         $features = array(
  151.                 'javascript'   => false,
  152.                 'dhtml'        => false,
  153.                 'dom'          => false,
  154.                 'sidebar'      => false,
  155.                 'gecko'        => false);
  156.  
  157.         // The leading identifier is the very first term in the user
  158.         // agent string, which is used to identify clients which are not
  159.         // Mosaic-based browsers.
  160.         $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier');
  161.  
  162.         // The full version of the client as supplied by the very first
  163.         // numbers in the user agent
  164.         $version = &Net_UserAgent_Detect::_getStaticProperty('version');
  165.         $version = 0;
  166.  
  167.         // The major part of the client version, which is the integer
  168.         // value of the version.
  169.         $majorVersion = &Net_UserAgent_Detect::_getStaticProperty('majorVersion');
  170.         $majorVersion = 0;
  171.  
  172.         // The minor part of the client version, which is the decimal
  173.         // parts of the version
  174.         $subVersion = &Net_UserAgent_Detect::_getStaticProperty('subVersion');
  175.         $subVersion = 0;
  176.  
  177.         // }}}
  178.         // detemine what user agent we are using
  179.         if (is_null($in_userAgent)) {
  180.             if (isset($_SERVER['HTTP_USER_AGENT'])) {
  181.                 $userAgent = $_SERVER['HTTP_USER_AGENT'];
  182.             }
  183.             elseif (isset($GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'])) {
  184.                 $userAgent = $GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'];
  185.             }
  186.             else {
  187.                 $userAgent = '';
  188.             }
  189.         }
  190.         else {
  191.             $userAgent = $in_userAgent;
  192.         }
  193.  
  194.         // get the lowercase version for case-insensitive searching
  195.         $agt = strtolower($userAgent);
  196.  
  197.         // figure out what we need to look for
  198.         $detectOptions = array(NET_USERAGENT_DETECT_BROWSER,
  199.                 NET_USERAGENT_DETECT_OS, NET_USERAGENT_DETECT_FEATURES,
  200.                 NET_USERAGENT_DETECT_QUIRKS, NET_USERAGENT_DETECT_ACCEPT, 
  201.                 NET_USERAGENT_DETECT_ALL);
  202.         $detect = is_null($in_detect) ? NET_USERAGENT_DETECT_ALL : $in_detect;
  203.         settype($detect, 'array');
  204.         foreach($detectOptions as $option) {
  205.             if (in_array($option, $detect)) {
  206.                 $detectFlags[$option] = true; 
  207.             }
  208.             else {
  209.                 $detectFlags[$option] = false;
  210.             }
  211.         }
  212.  
  213.         // initialize the arrays of browsers and operating systems
  214.  
  215.         // Get the type and version of the client
  216.         if (preg_match(";^([[:alnum:]]+)[ /\(]*[[:alpha:]]*([\d]*)(\.[\d\.]*);", $agt, $matches)) {
  217.             list(, $leadingIdentifier, $majorVersion, $subVersion) = $matches;
  218.         }
  219.  
  220.         if (empty($leadingIdentifier)) {
  221.             $leadingIdentifier = 'Unknown';
  222.         }
  223.  
  224.         $version = $majorVersion . $subVersion;
  225.     
  226.         // Browser type
  227.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_BROWSER]) {
  228.             $browser['konq']    = $browser['safari'] = (strpos($agt, 'konqueror') !== false || strpos($agt, 'safari') !== false);
  229.             $browser['text']    = (strpos($agt, 'links') !== false) || (strpos($agt, 'lynx') !== false) || (strpos($agt, 'w3m') !== false);
  230.             $browser['ns']      = (strpos($agt, 'mozilla') !== false) && !(strpos($agt, 'spoofer') !== false) && !(strpos($agt, 'compatible') !== false) && !(strpos($agt, 'hotjava') !== false) && !(strpos($agt, 'opera') !== false) && !(strpos($agt, 'webtv') !== false) ? 1 : 0;
  231.             $browser['ns2']     = $browser['ns'] && $majorVersion == 2;
  232.             $browser['ns3']     = $browser['ns'] && $majorVersion == 3;
  233.             $browser['ns4']     = $browser['ns'] && $majorVersion == 4;
  234.             $browser['ns4up']   = $browser['ns'] && $majorVersion >= 4;
  235.             // determine if this is a Netscape Navigator
  236.             $browser['nav']     = $browser['ns'] && $majorVersion < 5;
  237.             $browser['ns6']     = !$browser['konq'] && $browser['ns'] && $majorVersion == 5;
  238.             $browser['ns6up']   = $browser['ns6'] && $majorVersion >= 5;
  239.             $browser['gecko']   = (strpos($agt, 'gecko') !== false && !$browser['konq']);
  240.             $browser['ie']      = (strpos($agt, 'msie') !== false) && !(strpos($agt, 'opera') !== false);
  241.             $browser['ie3']     = $browser['ie'] && $majorVersion < 4;
  242.             $browser['ie4']     = $browser['ie'] && $majorVersion == 4 && (strpos($agt, 'msie 4') !== false);
  243.             $browser['ie4up']   = $browser['ie'] && !$browser['ie3'];
  244.             $browser['ie5']     = $browser['ie4up'] && (strpos($agt, 'msie 5.0') !== false);
  245.             $browser['ie5_5']   = $browser['ie4up'] && (strpos($agt, 'msie 5.5') !== false);
  246.             $browser['ie5up']   = $browser['ie4up'] && !$browser['ie3'] && !$browser['ie4'];
  247.             $browser['ie5_5up'] = $browser['ie5up'] && !$browser['ie5'];
  248.             $browser['ie6']     = (strpos($agt, 'msie 6') !== false);
  249.             $browser['ie6up']   = $browser['ie5up'] && !$browser['ie5'] && !$browser['ie5_5'];
  250.             $browser['opera']   = (strpos($agt, 'opera') !== false);
  251.             $browser['opera2']  = (strpos($agt, 'opera 2') !== false) || (strpos($agt, 'opera/2') !== false);
  252.             $browser['opera3']  = (strpos($agt, 'opera 3') !== false) || (strpos($agt, 'opera/3') !== false);
  253.             $browser['opera4']  = (strpos($agt, 'opera 4') !== false) || (strpos($agt, 'opera/4') !== false);
  254.             $browser['opera5']  = (strpos($agt, 'opera 5') !== false) || (strpos($agt, 'opera/5') !== false);
  255.             $browser['opera5up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'];
  256.  
  257.             $browser['aol']   = (strpos($agt, 'aol') !== false);
  258.             $browser['aol3']  = $browser['aol'] && $browser['ie3'];
  259.             $browser['aol4']  = $browser['aol'] && $browser['ie4'];
  260.             $browser['aol5']  = (strpos($agt, 'aol 5') !== false);
  261.             $browser['aol6']  = (strpos($agt, 'aol 6') !== false);
  262.             $browser['aol7']  = (strpos($agt, 'aol 7') !== false);
  263.             $browser['webtv'] = (strpos($agt, 'webtv') !== false); 
  264.             $browser['aoltv'] = $browser['tvnavigator'] = (strpos($agt, 'navio') !== false) || (strpos($agt, 'navio_aoltv') !== false); 
  265.             $browser['hotjava'] = (strpos($agt, 'hotjava') !== false);
  266.             $browser['hotjava3'] = $browser['hotjava'] && $majorVersion == 3;
  267.             $browser['hotjava3up'] = $browser['hotjava'] && $majorVersion >= 3;
  268.         }
  269.  
  270.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || 
  271.             ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) {
  272.             // Javascript Check
  273.             if ($browser['ns2'] || $browser['ie3']) {
  274.                 Net_UserAgent_Detect::setFeature('javascript', 1.0);
  275.             }
  276.             elseif ($browser['opera5up']) {
  277.                 Net_UserAgent_Detect::setFeature('javascript', 1.3);
  278.             }
  279.             elseif ($browser['opera'] || $browser['ns3']) {
  280.                 Net_UserAgent_Detect::setFeature('javascript', 1.1);
  281.             }
  282.             elseif (($browser['ns4'] && ($version <= 4.05)) || $browser['ie4']) {
  283.                 Net_UserAgent_Detect::setFeature('javascript', 1.2);
  284.             }
  285.             elseif (($browser['ie5up'] && strpos($agt, 'mac') !== false) || $browser['konq']) {
  286.                 Net_UserAgent_Detect::setFeature('javascript', 1.4);
  287.             }
  288.             // I can't believe IE6 still has javascript 1.3, what a shitty browser
  289.             elseif (($browser['ns4'] && ($version > 4.05)) || $browser['ie5up'] || $browser['hotjava3up']) {
  290.                 Net_UserAgent_Detect::setFeature('javascript', 1.3);
  291.             }
  292.             elseif ($browser['ns6up'] || $browser['gecko']) {
  293.                 Net_UserAgent_Detect::setFeature('javascript', 1.5);
  294.             }
  295.         }
  296.         
  297.         /** OS Check **/
  298.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_OS]) {
  299.             $os['win']   = (strpos($agt, 'win') !== false) || (strpos($agt, '16bit') !== false);
  300.             $os['win95'] = (strpos($agt, 'win95') !== false) || (strpos($agt, 'windows 95') !== false);
  301.             $os['win16'] = (strpos($agt, 'win16') !== false) || (strpos($agt, '16bit') !== false) || (strpos($agt, 'windows 3.1') !== false) || (strpos($agt, 'windows 16-bit') !== false);  
  302.             $os['win31'] = (strpos($agt, 'windows 3.1') !== false) || (strpos($agt, 'win16') !== false) || (strpos($agt, 'windows 16-bit') !== false);
  303.             $os['winme'] = (strpos($agt, 'win 9x 4.90') !== false);
  304.             $os['win2k'] = (strpos($agt, 'windows nt 5.0') !== false);
  305.             $os['winxp'] = (strpos($agt, 'windows nt 5.1') !== false);
  306.             $os['win98'] = (strpos($agt, 'win98') !== false) || (strpos($agt, 'windows 98') !== false);
  307.             $os['win9x'] = $os['win95'] || $os['win98'];
  308.             $os['winnt'] = ((strpos($agt, 'winnt') !== false) || (strpos($agt, 'windows nt') !== false)) && (strpos($agt, 'windows nt 5') === false);
  309.             $os['win32'] = $os['win95'] || $os['winnt'] || $os['win98'] || $majorVersion >= 4 && (strpos($agt, 'win32') !== false) || (strpos($agt, '32bit') !== false);
  310.             $os['os2']   = (strpos($agt, 'os/2') !== false) || (strpos($agt, 'ibm-webexplorer') !== false);
  311.             $os['mac']   = (strpos($agt, 'mac') !== false);
  312.             $os['mac68k']   = $os['mac'] && ((strpos($agt, '68k') !== false) || (strpos($agt, '68000') !== false));
  313.             $os['macppc']   = $os['mac'] && ((strpos($agt, 'ppc') !== false) || (strpos($agt, 'powerpc') !== false));
  314.             $os['sun']      = (strpos($agt, 'sunos') !== false);
  315.             $os['sun4']     = (strpos($agt, 'sunos 4') !== false);
  316.             $os['sun5']     = (strpos($agt, 'sunos 5') !== false);
  317.             $os['suni86']   = $os['sun'] && (strpos($agt, 'i86') !== false);
  318.             $os['irix']     = (strpos($agt, 'irix') !== false);
  319.             $os['irix5']    = (strpos($agt, 'irix 5') !== false);
  320.             $os['irix6']    = (strpos($agt, 'irix 6') !== false) || (strpos($agt, 'irix6') !== false);
  321.             $os['hpux']     = (strpos($agt, 'hp-ux') !== false);
  322.             $os['hpux9']    = $os['hpux'] && (strpos($agt, '09.') !== false);
  323.             $os['hpux10']   = $os['hpux'] && (strpos($agt, '10.') !== false);
  324.             $os['aix']      = (strpos($agt, 'aix') !== false);
  325.             $os['aix1']     = (strpos($agt, 'aix 1') !== false);    
  326.             $os['aix2']     = (strpos($agt, 'aix 2') !== false);    
  327.             $os['aix3']     = (strpos($agt, 'aix 3') !== false);    
  328.             $os['aix4']     = (strpos($agt, 'aix 4') !== false);    
  329.             $os['linux']    = (strpos($agt, 'inux') !== false);
  330.             $os['sco']      = (strpos($agt, 'sco') !== false) || (strpos($agt, 'unix_sv') !== false);
  331.             $os['unixware'] = (strpos($agt, 'unix_system_v') !== false); 
  332.             $os['mpras']    = (strpos($agt, 'ncr') !== false); 
  333.             $os['reliant']  = (strpos($agt, 'reliant') !== false);
  334.             $os['dec']      = (strpos($agt, 'dec') !== false) || (strpos($agt, 'osf1') !== false) || (strpos($agt, 'dec_alpha') !== false) || (strpos($agt, 'alphaserver') !== false) || (strpos($agt, 'ultrix') !== false) || (strpos($agt, 'alphastation') !== false);
  335.             $os['sinix']    = (strpos($agt, 'sinix') !== false);
  336.             $os['freebsd']  = (strpos($agt, 'freebsd') !== false);
  337.             $os['bsd']      = (strpos($agt, 'bsd') !== false);
  338.             $os['unix']     = (strpos($agt, 'x11') !== false) || (strpos($agt, 'unix') !== false) || $os['sun'] || $os['irix'] || $os['hpux'] || $os['sco'] || $os['unixware'] || $os['mpras'] || $os['reliant'] || $os['dec'] || $os['sinix'] || $os['aix'] || $os['linux'] || $os['bsd'] || $os['freebsd'];
  339.             $os['vms']      = (strpos($agt, 'vax') !== false) || (strpos($agt, 'openvms') !== false);
  340.         }
  341.  
  342.         // Setup the quirks
  343.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || 
  344.             ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_QUIRKS])) {
  345.             if ($browser['konq']) {
  346.                 Net_UserAgent_Detect::setQuirk('empty_file_input_value');
  347.             }
  348.  
  349.             if ($browser['ie']) {
  350.                 Net_UserAgent_Detect::setQuirk('cache_ssl_downloads');
  351.             }
  352.  
  353.             if ($browser['ie6']) {
  354.                 Net_UserAgent_Detect::setQuirk('scrollbar_in_way');
  355.             }
  356.  
  357.             if ($browser['ie5']) {
  358.                 Net_UserAgent_Detect::setQuirk('break_disposition_header');
  359.             }
  360.  
  361.             if ($browser['ns6']) {
  362.                 Net_UserAgent_Detect::setQuirk('popups_disabled');
  363.                 Net_UserAgent_Detect::setQuirk('must_cache_forms');
  364.             }
  365.             
  366.             if ($browser['nav'] && $subVersion < .79) {
  367.                 Net_UserAgent_Detect::setQuirk('nested_table_render_bug');
  368.             }
  369.         }
  370.             
  371.         // Set features
  372.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || 
  373.             ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) {
  374.             if ($browser['gecko']) {
  375.                 preg_match(';gecko/([\d]+)\b;i', $agt, $matches);
  376.                 Net_UserAgent_Detect::setFeature('gecko', $matches[1]);
  377.             }
  378.  
  379.             if ($browser['ns6up'] || $browser['opera5up'] || $browser['konq']) {
  380.                 Net_UserAgent_Detect::setFeature('dom');
  381.             }
  382.  
  383.             if ($browser['ie4up'] || $browser['ns4up'] || $browser['opera5up'] || $browser['konq']) {
  384.                 Net_UserAgent_Detect::setFeature('dhtml');
  385.             }
  386.         }
  387.  
  388.         if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_ACCEPT]) {
  389.             $mimetypes = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT'), 0, strpos(getenv('HTTP_ACCEPT') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
  390.             Net_UserAgent_Detect::setAcceptType((array) $mimetypes, 'mimetype');
  391.  
  392.             $languages = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_LANGUAGE'), 0, strpos(getenv('HTTP_ACCEPT_LANGUAGE') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
  393.             if (empty($languages)) {
  394.                 $languages = 'en';
  395.             }
  396.  
  397.             Net_UserAgent_Detect::setAcceptType((array) $languages, 'language');
  398.  
  399.             $encodings = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_ENCODING'), 0, strpos(getenv('HTTP_ACCEPT_ENCODING') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
  400.             Net_UserAgent_Detect::setAcceptType((array) $encodings, 'encoding');
  401.             
  402.             $charsets = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_CHARSET'), 0, strpos(getenv('HTTP_ACCEPT_CHARSET') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
  403.             Net_UserAgent_Detect::setAcceptType((array) $charsets, 'charset');
  404.         }
  405.     }
  406.     
  407.     // }}}
  408.     // {{{ setOption()
  409.  
  410.     /**
  411.      * Sets a class option.  The available settings are:
  412.      * o 'userAgent' => The user agent string to detect (useful for
  413.      * checking a string manually).
  414.      * o 'detectOptions' => The level of checking to do.  A single level
  415.      * or an array of options.  Default is NET_USERAGENT_DETECT_ALL.
  416.      *
  417.      * @param string $in_field The option field (userAgent or detectOptions)
  418.      * @param mixed $in_value The value for the field
  419.      */
  420.     function setOption($in_field, $in_value)
  421.     {
  422.         $options = &Net_UserAgent_Detect::_getStaticProperty('options');
  423.         $options[$in_field] = $in_value;
  424.     }
  425.  
  426.     // }}}
  427.     // {{{ isBrowser()
  428.  
  429.     /**
  430.      * Look up the provide browser flag and return a boolean value
  431.      *
  432.      * Given one of the flags listed in the properties, this function will return
  433.      * the value associated with that flag.
  434.      *
  435.      * @param  string $in_match flag to lookup
  436.      *
  437.      * @access public
  438.      * @return boolean whether or not the browser satisfies this flag
  439.      */
  440.     function isBrowser($in_match)
  441.     {
  442.         Net_UserAgent_Detect::detect();
  443.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  444.         return isset($browser[strtolower($in_match)]) ? $browser[strtolower($in_match)] : false;
  445.     }
  446.  
  447.     // }}}
  448.     // {{{ getBrowser()
  449.  
  450.     /**
  451.      * Since simply returning the "browser" is somewhat ambiguous since there
  452.      * are different ways to classify the browser, this function works by taking
  453.      * an expect list and returning the string of the first match, so put the important
  454.      * ones first in the array.
  455.      *
  456.      * @param  array $in_expectList the browser flags to search for
  457.      *
  458.      * @access public
  459.      * @return string first flag that matches
  460.      */
  461.     function getBrowser($in_expectList)
  462.     {
  463.         Net_UserAgent_Detect::detect();
  464.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  465.         foreach((array) $in_expectList as $brwsr) {
  466.             if (!empty($browser[strtolower($brwsr)])) {
  467.                 return $brwsr;
  468.             }
  469.         }
  470.     }
  471.  
  472.     // }}}
  473.     // {{{ getBrowserString()
  474.  
  475.     /**
  476.      * This function returns the vendor string corresponding to the flag.
  477.      *
  478.      * Either use the default matches or pass in an associative array of
  479.      * flags and corresponding vendor strings.  This function will find
  480.      * the highest version flag and return the vendor string corresponding
  481.      * to the appropriate flag.  Be sure to pass in the flags in ascending order
  482.      * if you want a basic matches first, followed by more detailed matches.
  483.      *
  484.      * @param  array $in_vendorStrings (optional) array of flags matched with vendor strings
  485.      *
  486.      * @access public
  487.      * @return string vendor string matches appropriate flag
  488.      */
  489.     function getBrowserString($in_vendorStrings = array (
  490.         'ie'       => 'Microsoft Internet Explorer',
  491.         'ie4up'    => 'Microsoft Internet Explorer 4.x',
  492.         'ie5up'    => 'Microsoft Internet Explorer 5.x',
  493.         'ie6up'    => 'Microsoft Internet Explorer 6.x',
  494.         'opera4'   => 'Opera 4.x',
  495.         'opera5up' => 'Opera 5.x',
  496.         'nav'      => 'Netscape Navigator',
  497.         'ns4'      => 'Netscape 4.x',
  498.         'ns6up'    => 'Mozilla/Netscape 6.x',
  499.         'konq'     => 'Konqueror/Safari',
  500.     ))
  501.     {
  502.         Net_UserAgent_Detect::detect();
  503.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  504.         foreach((array) $in_vendorStrings as $flag => $string) {
  505.             if (!empty($browser[$flag])) {
  506.                 $vendorString = $string;
  507.             }
  508.         }
  509.  
  510.         // if there are no matches just use the user agent leading idendifier (usually Mozilla)
  511.         if (!isset($vendorString)) {
  512.             $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier');
  513.             $vendorString = $leadingIdentifier;
  514.         }
  515.         
  516.         return $vendorString;
  517.     }
  518.  
  519.     // }}}
  520.     // {{{ isIE()
  521.  
  522.     /**
  523.      * Determine if the browser is an Internet Explorer browser
  524.      *
  525.      * @access public
  526.      * @return bool whether or not this browser is an ie browser
  527.      */
  528.     function isIE()
  529.     {
  530.         Net_UserAgent_Detect::detect();
  531.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  532.         return !empty($browser['ie']);
  533.     }
  534.  
  535.     // }}}
  536.     // {{{ isNavigator()
  537.  
  538.     /**
  539.      * Determine if the browser is a Netscape Navigator browser
  540.      *
  541.      * @access public
  542.      * @return bool whether or not this browser is a Netscape Navigator browser
  543.      */
  544.     function isNavigator()
  545.     {
  546.         Net_UserAgent_Detect::detect();
  547.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  548.         return !empty($browser['nav']);
  549.     }
  550.  
  551.     // }}}
  552.     // {{{ isNetscape()
  553.  
  554.     /**
  555.      * Determine if the browser is a Netscape or Mozilla browser
  556.      *
  557.      * Note that this function is not the same as isNavigator, since the
  558.      * new Mozilla browsers are still sponsered by Netscape, and hence are
  559.      * Netscape products, but not the original Navigators
  560.      *
  561.      * @access public
  562.      * @return bool whether or not this browser is a Netscape product
  563.      */
  564.     function isNetscape()
  565.     {
  566.         Net_UserAgent_Detect::detect();
  567.         $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
  568.         return !empty($browser['ns4up']);
  569.     }
  570.     
  571.     // }}}
  572.     // {{{ isOS()
  573.  
  574.     /**
  575.      * Look up the provide OS flag and return a boolean value
  576.      *
  577.      * Given one of the flags listed in the properties, this function will return
  578.      * the value associated with that flag for the operating system.
  579.      *
  580.      * @param  string $in_match flag to lookup
  581.      *
  582.      * @access public
  583.      * @return boolean whether or not the OS satisfies this flag
  584.      */
  585.     function isOS($in_match)
  586.     {
  587.         Net_UserAgent_Detect::detect();
  588.         $os = &Net_UserAgent_Detect::_getStaticProperty('os');
  589.         return isset($os[strtolower($in_match)]) ? $os[strtolower($in_match)] : false;
  590.     }
  591.  
  592.     // }}}
  593.     // {{{ getOS()
  594.  
  595.     /**
  596.      * Since simply returning the "os" is somewhat ambiguous since there
  597.      * are different ways to classify the browser, this function works by taking
  598.      * an expect list and returning the string of the first match, so put the important
  599.      * ones first in the array.
  600.      *
  601.      * @access public
  602.      * @return string first flag that matches
  603.      */
  604.     function getOS($in_expectList)
  605.     {
  606.         Net_UserAgent_Detect::detect();
  607.         $os = &Net_UserAgent_Detect::_getStaticProperty('os');
  608.         foreach((array) $in_expectList as $expectOs) {
  609.             if (!empty($os[strtolower($expectOs)])) {
  610.                 return $expectOs;
  611.             }
  612.         }
  613.     }
  614.  
  615.     // }}}
  616.     // {{{ getOSString()
  617.  
  618.     /**
  619.      * This function returns the os string corresponding to the flag.
  620.      *
  621.      * Either use the default matches or pass in an associative array of
  622.      * flags and corresponding os strings.  This function will find
  623.      * the highest version flag and return the os string corresponding
  624.      * to the appropriate flag.  Be sure to pass in the flags in ascending order
  625.      * if you want a basic matches first, followed by more detailed matches.
  626.      *
  627.      * @param  array $in_osStrings (optional) array of flags matched with os strings
  628.      *
  629.      * @access public
  630.      * @return string os string matches appropriate flag
  631.      */
  632.     function getOSString($in_osStrings = array(
  633.        'win'   => 'Microsoft Windows',
  634.        'win9x' => 'Microsoft Windows 9x',
  635.        'winme' => 'Microsoft Windows Millenium',
  636.        'win2k' => 'Microsoft Windows 2000',
  637.        'winnt' => 'Microsoft Windows NT',
  638.        'winxp' => 'Microsoft Windows XP',
  639.        'mac'   => 'Macintosh',
  640.        'unix'  => 'Linux/Unix',
  641.     ))
  642.     {
  643.         Net_UserAgent_Detect::detect();
  644.         $osString = 'Unknown';
  645.  
  646.         $os = &Net_UserAgent_Detect::_getStaticProperty('os');
  647.         foreach((array) $in_osStrings as $flag => $string) {
  648.             if (!empty($os[$flag])) {
  649.                 $osString = $string;
  650.             }
  651.         }
  652.  
  653.         return $osString;
  654.     }
  655.  
  656.     // }}}
  657.     // {{{ setQuirk()
  658.  
  659.     /**
  660.      * Set a unique behavior for the current browser.
  661.      *
  662.      * Many client browsers do some really funky things, and this
  663.      * mechanism allows the coder to determine if an excepetion must
  664.      * be made with the current client.
  665.      *
  666.      * @access public
  667.      * @return void
  668.      */
  669.     function setQuirk($in_quirk, $in_hasQuirk = true)
  670.     {
  671.         $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
  672.         $hasQuirk = !empty($in_hasQuirk); 
  673.         $quirks[strtolower($in_quirk)] = $hasQuirk;
  674.     }
  675.  
  676.     // }}}
  677.     // {{{ hasQuirk()
  678.  
  679.     /**
  680.      * Check a unique behavior for the current browser.
  681.      *
  682.      * Many client browsers do some really funky things, and this
  683.      * mechanism allows the coder to determine if an excepetion must
  684.      * be made with the current client.
  685.      *
  686.      * @access public
  687.      * @return bool whether or not browser has this quirk
  688.      */
  689.     function hasQuirk($in_quirk)
  690.     {
  691.         Net_UserAgent_Detect::detect();
  692.         $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
  693.         return !empty($quirks[strtolower($in_quirk)]);
  694.     }
  695.     
  696.     // }}}
  697.     // {{{ getQuirk()
  698.  
  699.     /**
  700.      * Get the unique behavior for the current browser.
  701.      *
  702.      * Many client browsers do some really funky things, and this
  703.      * mechanism allows the coder to determine if an excepetion must
  704.      * be made with the current client.
  705.      *
  706.      * @access public
  707.      * @return string value of the quirk, in this case usually a boolean
  708.      */
  709.     function getQuirk()
  710.     {
  711.         Net_UserAgent_Detect::detect();
  712.         $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
  713.         return isset($quirks[strtolower($in_quirks)]) ? $quirks[strtolower($in_quirks)] : null; 
  714.     }
  715.  
  716.     // }}}
  717.     // {{{ setFeature()
  718.  
  719.     /**
  720.      * Set capabilities for the current browser.
  721.      *
  722.      * Since the capabilities of client browsers vary widly, this interface
  723.      * helps keep track of the core features of a client, such as if the client
  724.      * supports dhtml, dom, javascript, etc.
  725.      *
  726.      * @access public
  727.      * @return void
  728.      */
  729.     function setFeature($in_feature, $in_hasFeature = true)
  730.     {
  731.         $features = &Net_UserAgent_Detect::_getStaticProperty('features');
  732.         $features[strtolower($in_feature)] = $in_hasFeature;
  733.     }
  734.  
  735.     // }}}
  736.     // {{{ hasFeature()
  737.  
  738.     /**
  739.      * Check the capabilities for the current browser.
  740.      *
  741.      * Since the capabilities of client browsers vary widly, this interface
  742.      * helps keep track of the core features of a client, such as if the client
  743.      * supports dhtml, dom, javascript, etc.
  744.      *
  745.      * @access public
  746.      * @return bool whether or not the current client has this feature
  747.      */
  748.     function hasFeature($in_feature)
  749.     {
  750.         Net_UserAgent_Detect::detect();
  751.         $features = &Net_UserAgent_Detect::_getStaticProperty('features');
  752.         return !empty($features[strtolower($in_feature)]);
  753.     }
  754.     
  755.     // }}}
  756.     // {{{ getFeature()
  757.  
  758.     /**
  759.      * Get the capabilities for the current browser.
  760.      *
  761.      * Since the capabilities of client browsers vary widly, this interface
  762.      * helps keep track of the core features of a client, such as if the client
  763.      * supports dhtml, dom, javascript, etc.
  764.      *
  765.      * @access public
  766.      * @return string value of the feature requested
  767.      */
  768.     function getFeature($in_feature)
  769.     {
  770.         Net_UserAgent_Detect::detect();
  771.         $features = &Net_UserAgent_Detect::_getStaticProperty('features');
  772.         return isset($features[strtolower($in_feature)]) ? $features[strtolower($in_feature)] : null; 
  773.     }
  774.  
  775.     // }}}
  776.     // {{{ getAcceptType()
  777.  
  778.     /**
  779.      * Retrive the accept type for the current browser.
  780.      *
  781.      * To keep track of the mime-types, languages, charsets and encodings
  782.      * that each browser accepts we use associative arrays for each type.
  783.      * This function works like getBrowser() as it takes an expect list
  784.      * and returns the first match.  For instance, to find the language
  785.      * you would pass in your allowed languages and see if any of the
  786.      * languages set in the browser match.
  787.      *
  788.      * @param  string $in_expectList values to check
  789.      * @param  string $in_type type of accept
  790.      *
  791.      * @access public
  792.      * @return string the first matched value
  793.      */
  794.     function getAcceptType($in_expectList, $in_type)
  795.     {
  796.         Net_UserAgent_Detect::detect();
  797.         $type = strtolower($in_type);
  798.  
  799.         if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') {
  800.             $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type);
  801.             foreach((array) $in_expectList as $match) {
  802.                 if (!empty($typeArray[$match])) {
  803.                     return $match;
  804.                 }
  805.             }
  806.         }
  807.  
  808.         return null;
  809.     }
  810.  
  811.     // }}}
  812.     // {{{ setAcceptType()
  813.  
  814.     /**
  815.      * Set the accept types for the current browser.
  816.      *
  817.      * To keep track of the mime-types, languages, charsets and encodings
  818.      * that each browser accepts we use associative arrays for each type.
  819.      * This function takes and array of accepted values for the type and
  820.      * records them for retrieval.
  821.      *
  822.      * @param  array $in_values values of the accept type
  823.      * @param  string $in_type type of accept
  824.      *
  825.      * @access public
  826.      * @return void
  827.      */
  828.     function setAcceptType($in_values, $in_type)
  829.     {
  830.         $type = strtolower($in_type);
  831.  
  832.         if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') {
  833.             $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type);
  834.             foreach((array) $in_values as $value) {
  835.                 $typeArray[$value] = true;
  836.             }
  837.         }
  838.     }
  839.  
  840.     // }}}
  841.     // {{{ hasAcceptType()
  842.  
  843.     /**
  844.      * Check the accept types for the current browser.
  845.      *
  846.      * To keep track of the mime-types, languages, charsets and encodings
  847.      * that each browser accepts we use associative arrays for each type.
  848.      * This function checks the array for the given type and determines if
  849.      * the browser accepts it.
  850.      *
  851.      * @param  string $in_value values to check
  852.      * @param  string $in_type type of accept
  853.      *
  854.      * @access public
  855.      * @return bool whether or not the value is accept for this type
  856.      */
  857.     function hasAcceptType($in_value, $in_type)
  858.     {
  859.         Net_UserAgent_Detect::detect();
  860.         $type = strtolower($in_type);
  861.  
  862.         if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') {
  863.             $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type);
  864.             return !empty($typeArray[$in_value]);
  865.         }
  866.         else {
  867.             return false;
  868.         }
  869.     }
  870.  
  871.     // }}}
  872.     // {{{ getUserAgent()
  873.  
  874.     /**
  875.      * Return the user agent string that is being worked on
  876.      *
  877.      * @access public
  878.      * @return string user agent
  879.      */
  880.     function getUserAgent()
  881.     {
  882.         Net_UserAgent_Detect::detect();
  883.         $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent');
  884.         return $userAgent;
  885.     }
  886.  
  887.     // }}}
  888.     // {{{ _getStaticProperty()
  889.  
  890.     /**
  891.      * Copy of getStaticProperty() from PEAR.php to avoid having to
  892.      * include PEAR.php
  893.      *
  894.      * @access private
  895.      * @param  string $var    The variable to retrieve.
  896.      * @return mixed   A reference to the variable. If not set it will be
  897.      *                 auto initialised to NULL.
  898.      */
  899.     function &_getStaticProperty($var)
  900.     {
  901.         static $properties;
  902.         return $properties[$var];
  903.     }
  904.  
  905.     // }}}
  906. }
  907. ?>
  908.